<?php

namespace tools\lib\main\model;

use tools\lib\main\Common;

/**
 * 创建logic
 * Class Logic
 * @package app\common\command\create\file
 */
class Logic extends Common
{

    private $constant = [];

    /**
     * @return string
     * @throws \ReflectionException
     */
    public function template()
    {

        $constants = $this->transConstant();

        $class_name = preg_replace('/Logic/', '', $this->className());

        $model = preg_replace('/Logic/', 'Model', $this->className());

        $model_namespace = $this->getFileProperties('model_namespace') ?: $this->getFileProperties('namespace');

        if (empty($model_namespace)) {
            return '';
        }

        // 同一目录下,不需要使用use
        if ($this->namespace == $model_namespace) {
            $model_namespace = '';
        } else {
            $model_namespace = 'use ' . $model_namespace . '\\' . $model . ';';
        }

        $template = <<<EOT
<?php

{$this->getFileNamespace()}

{$this->getFileUse()}
$model_namespace

class $class_name {$this->getFileExtends()}
{
    $constants

    /**
     * @var array 
     */
    public \$fields = {$this->transSelectField()};

    /**
     * @return $model|\\think\Model
     */
    protected function model()
    {
        return new $model();
    }
    
    {$this->select()}
}
EOT;

        return $template;
    }

    /**
     * @return string
     * @throws \ReflectionException
     */
    public function transAction()
    {
        $template = '' . "\n";

        $columns = tableColumns($this->parameter->getName());

        if ($columns) {
            foreach ($columns as $column) {

                $field = $column['Field'];

                /**
                 * 如果字段中包含name，title等字段信息，则自动追加getName,getTitle信息
                 * 这里是tp中自己封装的一个MainLogic，特定的数据信息，暂时没有优化这里的数据
                 */
                if (in_array($field, ['name', 'title'])) {
                    $template .= $this->getFieldMethods($field);
                }
            }
        }

        $template = rtrim($template, "\n");

        return $template;
    }

    /**
     * 数据库表中可以筛选的字段信息
     * @return string
     */
    public function transSelectField()
    {
        $columns = tableColumns($this->parameter->getName());

        $params = [];

        if ($columns) {
            foreach ($columns as $column) {

                $field = $column['Field'];

                if (in_array($field, ['update_time', 'delete_time'])) {
                    continue;
                }

                $params[] = $field;
            }
        }

        return concatArrayFormatNoKey($params);
    }

    /**
     * @param $field
     * @return string
     */
    private function getFieldMethods($field)
    {

        $name = transToPascal($field);

        $template = <<<EOF

    /**
     * @param bool \$withTrashed
     * @return array
     */
    public function get$name(\$withTrashed = false)
    {
        return \$this->setWithTrashed(\$withTrashed)->column('id,$field');
    }

EOF;

        return $template;
    }

    private function create()
    {
        $template = <<<EOF
/**
     * @param array \$data
     * @return mixed
     */
    public function save(array \$data)
    {
        return \$this->setValidate(\$data)->save(\$data);
    }
EOF;
        $template = rtrim($template, "\n");

        return $template;

    }

    private function select()
    {
        $template = '' . "\n";

        $columns = tableColumns($this->parameter->getName());

        if ($columns) {
            foreach ($columns as $column) {

                $field = $column['Field'];

                if (in_array($field, ['id', 'update_time', 'create_time', 'delete_time'])) {
                    continue;
                }

                if (!preg_match('/_id|_no/', $field) && !in_array($field, ['phone'])) {
                    continue;
                }

                $method = transToPascal($field);

                $field = transToUnderline($field);

                $param = '$' . $field . '';

                $template .= <<<EOF
    /**
     * @param $param
     * @return array|bool|null
     */
    public function getBy$method($param)
    {
        if (empty($param)) {
            return false;
        }
        return \$this->find(['$field' => $param]);
    }
EOF;
            }
        }


        $template = rtrim($template, "\n");

        return $template;
    }


    /**
     * @return bool|string
     */
    private function transConstant()
    {
        $this->constant = $this->constant ? $this->constant : $this->findConstantFromModel();

        if (empty($this->constant)) {
            return '';
        }

        $template = '' . "\n";

        foreach ($this->constant as $item) {

            if (!is_array($item)) {
                dump('create constant fail: options is not array');
                return false;
            }

            if (count($item) != 3) {
                dump('create constant fail: options params short');
                return false;
            }

            if (!$variable = $item[0]) {
                return false;
            };

            $variable = strtoupper($variable);
            $value = $item[1] ? $item[1] : 0;
            $comment = $item[2] ? $item[2] : '';

            $template .= <<<ETO
    /**
     * $comment
     * @var int
     */
    const $variable = $value;
ETO;
            $template .= "\n\n";
        }

        $template = rtrim($template, "\n");

        return $template;
    }

    /**
     * @return array
     */
    private function findConstantFromModel()
    {
        $columns = tableColumns($this->parameter->getName());


        $constant = [];
        if ($columns) {
            foreach ($columns as $column) {
                $field_name = $column['Field'];
                $field_type = $column['Type'];
                $field_comment = $column['Comment'];
                if (preg_match('/tinyint/', $field_type) || in_array($field_name, ['status', 'type', 'action'])) {

                    $field_comment = parseFieldComment($field_comment);

                    if ($field_comment) {
                        foreach ($field_comment as $key => $comment) {
                            if (count($comment) != 3 || !preg_match('/^[a-zA-Z]+/', $comment[2])) {
                                break 1;
                            }
                            $description = $comment[1];
                            $value = $comment[0];
                            $name = $comment[2];
                            $constant[] = [
                                // 常量名称
                                $field_name . '_' . $name,
                                // 常量值
                                $value,
                                // 常量备注
                                $description
                            ];
                        }
                    }
                }
            }
        }

        return $constant;
    }
}